// 音频系统 - Stage 3
// 使用Web Audio API生成程序化音效，无需外部音频文件

export enum SoundType {
    MISSILE_LAUNCH = 'missile_launch',
    MISSILE_FLIGHT = 'missile_flight',
    EXPLOSION = 'explosion',
    INTERCEPT = 'intercept',
    WARNING = 'warning',
    SYSTEM_BEEP = 'system_beep',
    AMBIENT_TENSION = 'ambient_tension',
    VICTORY = 'victory',
    DEFEAT = 'defeat',
    UI_CLICK = 'ui_click',
    RADAR_SWEEP = 'radar_sweep'
}

interface SoundConfig {
    type: SoundType;
    volume: number;
    duration: number;
    frequency: number;
    frequencyEnd?: number;
    waveform: OscillatorType;
    envelope: {
        attack: number;
        decay: number;
        sustain: number;
        release: number;
    };
    effects?: {
        reverb?: boolean;
        lowpass?: number;
        highpass?: number;
    };
}

// 音效配置
const SOUND_CONFIGS: Record<SoundType, SoundConfig> = {
    [SoundType.MISSILE_LAUNCH]: {
        type: SoundType.MISSILE_LAUNCH,
        volume: 0.6,
        duration: 1.5,
        frequency: 60,
        frequencyEnd: 120,
        waveform: 'sawtooth',
        envelope: { attack: 0.1, decay: 0.3, sustain: 0.7, release: 0.8 },
        effects: { reverb: true, lowpass: 800 }
    },
    [SoundType.MISSILE_FLIGHT]: {
        type: SoundType.MISSILE_FLIGHT,
        volume: 0.3,
        duration: 0.5,
        frequency: 200,
        frequencyEnd: 180,
        waveform: 'sine',
        envelope: { attack: 0.05, decay: 0.1, sustain: 0.8, release: 0.1 },
        effects: { lowpass: 1200 }
    },
    [SoundType.EXPLOSION]: {
        type: SoundType.EXPLOSION,
        volume: 0.8,
        duration: 2.0,
        frequency: 50,
        frequencyEnd: 20,
        waveform: 'sawtooth',
        envelope: { attack: 0.01, decay: 0.2, sustain: 0.3, release: 1.5 },
        effects: { reverb: true }
    },
    [SoundType.INTERCEPT]: {
        type: SoundType.INTERCEPT,
        volume: 0.5,
        duration: 0.8,
        frequency: 800,
        frequencyEnd: 400,
        waveform: 'square',
        envelope: { attack: 0.01, decay: 0.1, sustain: 0.2, release: 0.5 },
        effects: { highpass: 300 }
    },
    [SoundType.WARNING]: {
        type: SoundType.WARNING,
        volume: 0.7,
        duration: 1.0,
        frequency: 880,
        frequencyEnd: 440,
        waveform: 'sine',
        envelope: { attack: 0.1, decay: 0.2, sustain: 0.6, release: 0.3 },
        effects: { reverb: true }
    },
    [SoundType.SYSTEM_BEEP]: {
        type: SoundType.SYSTEM_BEEP,
        volume: 0.4,
        duration: 0.2,
        frequency: 1000,
        waveform: 'sine',
        envelope: { attack: 0.01, decay: 0.05, sustain: 0.8, release: 0.1 }
    },
    [SoundType.AMBIENT_TENSION]: {
        type: SoundType.AMBIENT_TENSION,
        volume: 0.2,
        duration: 5.0,
        frequency: 40,
        frequencyEnd: 60,
        waveform: 'sine',
        envelope: { attack: 1.0, decay: 1.0, sustain: 0.6, release: 2.0 },
        effects: { reverb: true, lowpass: 200 }
    },
    [SoundType.VICTORY]: {
        type: SoundType.VICTORY,
        volume: 0.6,
        duration: 2.0,
        frequency: 440,
        frequencyEnd: 880,
        waveform: 'sine',
        envelope: { attack: 0.1, decay: 0.3, sustain: 0.7, release: 1.0 },
        effects: { reverb: true }
    },
    [SoundType.DEFEAT]: {
        type: SoundType.DEFEAT,
        volume: 0.6,
        duration: 3.0,
        frequency: 220,
        frequencyEnd: 110,
        waveform: 'sawtooth',
        envelope: { attack: 0.2, decay: 0.5, sustain: 0.4, release: 2.0 },
        effects: { reverb: true, lowpass: 400 }
    },
    [SoundType.UI_CLICK]: {
        type: SoundType.UI_CLICK,
        volume: 0.3,
        duration: 0.1,
        frequency: 1200,
        waveform: 'square',
        envelope: { attack: 0.01, decay: 0.03, sustain: 0.0, release: 0.05 }
    },
    [SoundType.RADAR_SWEEP]: {
        type: SoundType.RADAR_SWEEP,
        volume: 0.25,
        duration: 1.0,
        frequency: 300,
        frequencyEnd: 600,
        waveform: 'sine',
        envelope: { attack: 0.1, decay: 0.2, sustain: 0.3, release: 0.4 },
        effects: { lowpass: 800 }
    }
};

interface ActiveSound {
    id: string;
    type: SoundType;
    source: AudioBufferSourceNode;
    gainNode: GainNode;
    startTime: number;
    duration: number;
}

export class AudioSystem {
    private audioContext: AudioContext | null = null;
    private masterGain: GainNode | null = null;
    private reverbNode: ConvolverNode | null = null;
    private activeSounds: Map<string, ActiveSound> = new Map();
    private nextSoundId = 0;
    private enabled = true;
    private masterVolume = 0.7;

    constructor() {
        this.initializeAudioContext();
    }

    private async initializeAudioContext(): Promise<void> {
        try {
            // 创建AudioContext
            this.audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();
            
            // 创建主音量控制
            this.masterGain = this.audioContext.createGain();
            this.masterGain.gain.value = this.masterVolume;
            this.masterGain.connect(this.audioContext.destination);
            
            // 创建混响效果
            await this.createReverbEffect();
            
            console.log('🔊 音频系统初始化完成');
        } catch (error) {
            console.warn('⚠️ 音频系统初始化失败:', error);
            this.enabled = false;
        }
    }

    private async createReverbEffect(): Promise<void> {
        if (!this.audioContext) return;

        this.reverbNode = this.audioContext.createConvolver();
        
        // 创建人工混响脉冲响应
        const sampleRate = this.audioContext.sampleRate;
        const length = sampleRate * 2; // 2秒混响
        const impulse = this.audioContext.createBuffer(2, length, sampleRate);
        
        for (let channel = 0; channel < 2; channel++) {
            const channelData = impulse.getChannelData(channel);
            for (let i = 0; i < length; i++) {
                const decay = Math.pow(1 - i / length, 2);
                channelData[i] = (Math.random() * 2 - 1) * decay * 0.1;
            }
        }
        
        this.reverbNode.buffer = impulse;
        this.reverbNode.connect(this.masterGain!);
    }

    public async playSound(type: SoundType, volume: number = 1.0): Promise<string> {
        if (!this.enabled || !this.audioContext || !this.masterGain) {
            return '';
        }

        // 如果AudioContext被暂停，尝试恢复
        if (this.audioContext.state === 'suspended') {
            await this.audioContext.resume();
        }

        const config = SOUND_CONFIGS[type];
        if (!config) return '';

        const soundId = `sound_${this.nextSoundId++}`;
        
        try {
            // 创建音频缓冲区
            const buffer = await this.generateSoundBuffer(config);
            
            // 创建源节点
            const source = this.audioContext.createBufferSource();
            source.buffer = buffer;
            
            // 创建增益节点
            const gainNode = this.audioContext.createGain();
            gainNode.gain.value = config.volume * volume;
            
            // 连接音频图
            source.connect(gainNode);
            
            // 处理音效
            if (config.effects?.reverb && this.reverbNode) {
                const dryGain = this.audioContext.createGain();
                const wetGain = this.audioContext.createGain();
                dryGain.gain.value = 0.7;
                wetGain.gain.value = 0.3;
                
                gainNode.connect(dryGain);
                gainNode.connect(wetGain);
                dryGain.connect(this.masterGain);
                wetGain.connect(this.reverbNode);
            } else {
                gainNode.connect(this.masterGain);
            }
            
            // 开始播放
            const currentTime = this.audioContext.currentTime;
            source.start(currentTime);
            
            // 记录活跃声音
            const activeSound: ActiveSound = {
                id: soundId,
                type,
                source,
                gainNode,
                startTime: currentTime,
                duration: config.duration
            };
            
            this.activeSounds.set(soundId, activeSound);
            
            // 设置自动清理
            source.onended = () => {
                this.activeSounds.delete(soundId);
            };
            
            return soundId;
            
        } catch (error) {
            console.warn('⚠️ 播放音效失败:', error);
            return '';
        }
    }

    private async generateSoundBuffer(config: SoundConfig): Promise<AudioBuffer> {
        if (!this.audioContext) throw new Error('AudioContext not initialized');

        const sampleRate = this.audioContext.sampleRate;
        const samples = Math.floor(sampleRate * config.duration);
        const buffer = this.audioContext.createBuffer(1, samples, sampleRate);
        const data = buffer.getChannelData(0);

        // 生成基础波形
        for (let i = 0; i < samples; i++) {
            const t = i / sampleRate;
            const progress = i / samples;
            
            // 频率变化
            let frequency = config.frequency;
            if (config.frequencyEnd) {
                frequency = config.frequency + (config.frequencyEnd - config.frequency) * progress;
            }
            
            // 生成波形
            const phase = 2 * Math.PI * frequency * t;
            let sample = 0;
            
            switch (config.waveform) {
                case 'sine':
                    sample = Math.sin(phase);
                    break;
                case 'square':
                    sample = Math.sign(Math.sin(phase));
                    break;
                case 'sawtooth':
                    sample = 2 * (phase / (2 * Math.PI) - Math.floor(phase / (2 * Math.PI) + 0.5));
                    break;
                case 'triangle':
                    sample = 2 * Math.abs(2 * (phase / (2 * Math.PI) - Math.floor(phase / (2 * Math.PI) + 0.5))) - 1;
                    break;
            }
            
            // 应用包络
            const envelope = this.calculateEnvelope(progress, config.envelope);
            data[i] = sample * envelope;
        }

        return buffer;
    }

    private calculateEnvelope(progress: number, envelope: SoundConfig['envelope']): number {
        const { attack, decay, sustain, release } = envelope;
        const totalTime = attack + decay + release;
        
        if (progress < attack / totalTime) {
            // Attack phase
            return progress / (attack / totalTime);
        } else if (progress < (attack + decay) / totalTime) {
            // Decay phase
            const decayProgress = (progress - attack / totalTime) / (decay / totalTime);
            return 1 - decayProgress * (1 - sustain);
        } else if (progress < (attack + decay + (1 - totalTime)) / 1) {
            // Sustain phase
            return sustain;
        } else {
            // Release phase
            const releaseProgress = (progress - (attack + decay + (1 - totalTime)) / 1) / (release / totalTime);
            return sustain * (1 - releaseProgress);
        }
    }

    public stopSound(soundId: string): void {
        const activeSound = this.activeSounds.get(soundId);
        if (activeSound) {
            activeSound.source.stop();
            this.activeSounds.delete(soundId);
        }
    }

    public stopAllSounds(): void {
        for (const [soundId, activeSound] of this.activeSounds) {
            activeSound.source.stop();
        }
        this.activeSounds.clear();
    }

    public setMasterVolume(volume: number): void {
        this.masterVolume = Math.max(0, Math.min(1, volume));
        if (this.masterGain) {
            this.masterGain.gain.value = this.masterVolume;
        }
    }

    public getMasterVolume(): number {
        return this.masterVolume;
    }

    public setEnabled(enabled: boolean): void {
        this.enabled = enabled;
        if (!enabled) {
            this.stopAllSounds();
        }
    }

    public isEnabled(): boolean {
        return this.enabled;
    }

    public getActiveSoundCount(): number {
        return this.activeSounds.size;
    }

    // 游戏特定的音效方法
    public playMissileLaunch(): void {
        this.playSound(SoundType.MISSILE_LAUNCH, 0.8);
    }

    public playMissileExplosion(): void {
        this.playSound(SoundType.EXPLOSION, 1.0);
    }

    public playIntercept(): void {
        this.playSound(SoundType.INTERCEPT, 0.7);
    }

    public playWarning(): void {
        this.playSound(SoundType.WARNING, 0.9);
    }

    public playSystemBeep(): void {
        this.playSound(SoundType.SYSTEM_BEEP, 0.5);
    }

    public playUIClick(): void {
        this.playSound(SoundType.UI_CLICK, 0.4);
    }

    public startAmbientTension(): Promise<string> {
        return this.playSound(SoundType.AMBIENT_TENSION, 0.6);
    }

    public playRadarSweep(): void {
        this.playSound(SoundType.RADAR_SWEEP, 0.3);
    }

    public playVictory(): void {
        this.playSound(SoundType.VICTORY, 0.8);
    }

    public playDefeat(): void {
        this.playSound(SoundType.DEFEAT, 0.8);
    }

    public update(deltaTime: number): void {
        if (!this.audioContext) return;

        const currentTime = this.audioContext.currentTime;
        
        // 清理已结束的声音
        for (const [soundId, activeSound] of this.activeSounds) {
            if (currentTime - activeSound.startTime > activeSound.duration) {
                this.activeSounds.delete(soundId);
            }
        }
    }

    public destroy(): void {
        this.stopAllSounds();
        if (this.audioContext) {
            this.audioContext.close();
            this.audioContext = null;
        }
    }
}
